/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef MEMCACHED_H
#define MEMCACHED_H

/** \file
 * The main memcached header holding commonly used data
 * structures and function prototypes.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <event.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
#include <net/if.h>
#include <list>

#include "net/event_msgqueue.h"
#include "net/net.h"

#include <glog/logging.h>


using namespace std;

 #include<stdio.h>
 #include<unistd.h>
 #include<signal.h>
 #include<sys/wait.h>
 #include<sys/ioctl.h>
 #include<sys/socket.h>
 #include<fcntl.h> 
 #include<errno.h>

#define OK 1
#define ERROR      -1
#define  AGAIN      -2
#define MAX_PROCESSES 1024
#define PROCESSES_NUM 2
#define PROCESS_DETACHED      -4
#define INVALID_PID -1

#define PROCESS_MASTER   1
#define PROCESS_WORKER   2

#define PROCESS_NORESPAWN     -1
#define PROCESS_RESPAWN       -2
#define PROCESS_JUST_RESPAWN  -3
#define PROCESS_DETACHED      -4

#define CMD_OPEN_CHANNEL   1
#define CMD_CLOSE_CHANNEL  2
#define CMD_QUIT           3
#define CMD_TERMINATE      4
#define CMD_REOPEN         5

#define SHUTDOWN_SIGNAL      QUIT
#define TERMINATE_SIGNAL     TERM
#define NOACCEPT_SIGNAL      WINCH
#define RECONFIGURE_SIGNAL   HUP

#define REOPEN_SIGNAL        USR1
#define CHANGEBIN_SIGNAL     USR2

#define signal_helper(n)     SIG##n
#define signal_value(n)      signal_helper(n)
#define value_helper(n)      #n
#define value_(n)             value_helper(n)

/** Maximum length of a key. */
#define KEY_MAX_LENGTH 250

/** Size of an incr buf. */
#define INCR_MAX_STORAGE_LEN 24

#define DATA_BUFFER_SIZE 2048
#define UDP_READ_BUFFER_SIZE 65536
#define UDP_MAX_PAYLOAD_SIZE 1400
#define UDP_HEADER_SIZE 8
#define MAX_SENDBUF_SIZE (256 * 1024 * 1024)

/** High water marks for buffer shrinking */
#define READ_BUFFER_HIGHWAT 8192
#define ITEM_LIST_HIGHWAT 400
#define IOV_LIST_HIGHWAT 600
#define MSG_LIST_HIGHWAT 100

/* Binary protocol stuff */
#define MIN_BIN_PKT_LENGTH 16
#define BIN_PKT_HDR_WORDS (MIN_BIN_PKT_LENGTH/sizeof(uint32_t))

/* unistd.h is here */
#if HAVE_UNISTD_H
# include <unistd.h>
#endif

/* Slab sizing definitions. */
#define POWER_SMALLEST 1
#define POWER_LARGEST  200
#define CHUNK_ALIGN_BYTES 8
#define DONT_PREALLOC_SLABS
#define MAX_NUMBER_OF_SLAB_CLASSES (POWER_LARGEST + 1)


#define STAT_KEY_LEN 128
#define STAT_VAL_LEN 128

/** Append an indexed stat with a stat name (with format), value format
    and value */
#define APPEND_NUM_FMT_STAT(name_fmt, num, name, fmt, val)          \
    klen = snprintf(key_str, STAT_KEY_LEN, name_fmt, num, name);    \
    vlen = snprintf(val_str, STAT_VAL_LEN, fmt, val);               \
    add_stats(key_str, klen, val_str, vlen, c);

/** Common APPEND_NUM_FMT_STAT format. */
#define APPEND_NUM_STAT(num, name, fmt, val) \
    APPEND_NUM_FMT_STAT("%d:%s", num, name, fmt, val)


enum network_transport {
    tcp_transport
};

#define IS_TCP(x) (x == tcp_transport)

#define MAX_VERBOSITY_LEVEL 2

/* When adding a setting, be sure to update process_stat_settings */
/**
 * Globally accessible settings as derived from the commandline.
 */
struct settings 
{
    int maxconns;
    int port;
    int listenfd;
    char *logpath;   /* path to log if writing log */
    int num_threads_per_process;
    int num_processes;        
    char *engine_soname;
    int  engine_argc;
    char *engine_args;
    char **engine_argv;
    bool do_daemonize;
    char *master_pid_file;
    int  pid_file_fd;
    int  queue_lwm;
    int  queue_hwm;
    bool enable_async_process;
    list<net_interface_t*> interfaces;
};

extern struct settings settings;
//extern GPrivate* g_server_private_key;

/*
 * Functions
 */
extern int daemonize(int nochdir, int noclose);

#include "net/request.h"
request_t* request_new();
void request_free(request_t* request);

#include "utility/util.h"

#if HAVE_DROP_PRIVILEGES
extern void drop_privileges(void);
#else
#define drop_privileges()
#endif

/* If supported, give compiler hints for branch prediction. */
#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
#define __builtin_expect(x, expected_value) (x)
#endif

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)
#endif
